package com.zhangtai.config;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.zhangtai.Neusoft.constVo.EmployeeInfoConst;
//import com.zhangtai.Neusoft.service.NeuEmployeeBaseInfoService;
import com.zhangtai.common.annotation.SysAuthorityLog;
import com.zhangtai.exception.QwMsg;
import com.zhangtai.modules.constVo.BpmConst;
import com.zhangtai.modules.constVo.NoticeConst;
import com.zhangtai.modules.constVo.SalaryConst;
import com.zhangtai.modules.controller.aouthLogin.LoginController;
import com.zhangtai.modules.dao.ContractUrlDao;
import com.zhangtai.modules.dao.EmployeeInfoDao;
import com.zhangtai.modules.dao.SalaryChangeDao;
import com.zhangtai.modules.dao.UserDao;
//import com.zhangtai.modules.dao.ssqlDao.EmployeeBaseDao;
import com.zhangtai.modules.entity.common.ContractUrlEntity;
import com.zhangtai.modules.entity.common.MailRecordEntity;
import com.zhangtai.modules.entity.employee.EmployeeInfoEntity;
import com.zhangtai.modules.entity.flow.FlowEntity;
import com.zhangtai.modules.entity.salary.SalaryChangeEntity;
import com.zhangtai.modules.entity.salary.SalaryDistributionEntity;
import com.zhangtai.modules.entity.system.AuthorityLogEntity;
import com.zhangtai.modules.entity.system.UserEntity;
import com.zhangtai.modules.service.common.ContractUrlService;
import com.zhangtai.modules.service.common.MailRecordService;
import com.zhangtai.modules.service.employee.EmployeeInfoService;
import com.zhangtai.modules.service.salary.SalaryChangeService;
import com.zhangtai.modules.service.system.AuthorityLogService;
import com.zhangtai.modules.service.system.LogService;
import com.zhangtai.modules.vo.MailVo;
import com.zhangtai.utils.DateUtils;
import com.zhangtai.utils.SnowflakeIdWorker;
import com.zhangtai.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: ming
 * @Date: 2020/6/2 0002 下午 4:28
 */
@Component
@Slf4j
public class AsyncMethod {
    @Autowired
    private ContractUrlDao contractUrlDao;
    @Autowired
    private ContractUrlService contractUrlService;
    @Autowired
    private MailRecordService mailRecordService;
    @Autowired
    private EmployeeInfoService employeeInfoService;
    @Autowired
    private LoginController loginController;
    @Autowired
    private AuthorityLogService authorityLogService;
    @Autowired
    private LogService logService;
    @Autowired
    private UserDao userDao;
    @Autowired
    private EmployeeInfoDao employeeInfoDao;
    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;
    @Autowired
    private SalaryChangeService salaryChangeService;
    @Autowired
    private SalaryChangeDao salaryChangeDao;
    @Autowired
    private QwMsg qwMsg;
//    @Autowired
//    private NeuEmployeeBaseInfoService neuEmployeeBaseInfoService;
//    @Autowired
//    private EmployeeBaseDao employeeBaseDao;



    @Async("Log")
    public void save(ContractUrlEntity contractUrlEntity) throws Exception {

        log.info("当前线程：{}",Thread.currentThread().getName());
        contractUrlDao.insert(contractUrlEntity);
    }


    @Async("Log")
    public void updateAndUploadAndStatus(ContractUrlEntity contractUrlEntity) throws Exception {


        log.info("当前签约线程：{},流程id:{},url:{}",Thread.currentThread().getName(),contractUrlEntity.getFlowId(),contractUrlEntity.getContractEsignUrl());
//        log.info("异步签约修改参数：{}",contractUrlEntity);
        //上传并保存url
        contractUrlService.uploadToOssAndUpdate(contractUrlEntity);





    }



    /**
     * 保存邮件发送记录
     * @param mailVo
     */
    @Async("Log")
    public void saveMailLog(MailVo mailVo, Integer status, String name) throws Exception {
        log.info("当前线程：{}",Thread.currentThread().getName());

        EmployeeInfoEntity byIdE = employeeInfoService.getByIdE(mailVo.getOid());
        MailRecordEntity mailRecordEntity = new MailRecordEntity();
        mailRecordEntity.setOid(mailVo.getOid());
        mailRecordEntity.setTitle(mailVo.getSubject());
        mailRecordEntity.setReceive(mailVo.getReceive());
        mailRecordEntity.setStatus(status);
        mailRecordEntity.setCreateTime(new Date());
        mailRecordEntity.setName(byIdE.getName());
        mailRecordEntity.setSendName(name);
        mailRecordEntity.setSendOid(mailVo.getSendOid());
        List<String> url = mailVo.getUrl();
        if (!CollectionUtils.isEmpty(url)){
            mailRecordEntity.setAttachment(url.toString());
        }
        if (mailVo.getType()!=null){
            mailRecordEntity.setType(mailVo.getType());
        }
        mailRecordService.saveE(mailRecordEntity);
    }

    /**
     * 保存用户操作记录
     * @param joinPoint
     * @param keys
     */
    @Async("Log")
    public void saveSysAuthorityLog(JoinPoint joinPoint, Object keys,String ip,String requestURI,JSONObject userInfo ) throws Exception {
        log.info("当前线程：{}",Thread.currentThread().getName());
        // 开始时间
        long beginTime = Instant.now().toEpochMilli();
        AuthorityLogEntity authorityLogEntity = new AuthorityLogEntity();
        if (!ObjectUtils.isEmpty(userInfo)) {
            UserEntity userEntity = userDao.selectById(userInfo.getLong("id"));
            authorityLogEntity.setJobId(userEntity.getJobId());
            authorityLogEntity.setJobName(userEntity.getJobname());
            authorityLogEntity.setUpdateUserName(userEntity.getName());
            authorityLogEntity.setUpdateUserId(userEntity.getUserId());
            authorityLogEntity.setUsercode(userEntity.getUsercode());
            authorityLogEntity.setOrgId(userInfo.getLong("orgId"));
        }

        // 从切面织入点处通过反射机制获取织入点处的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 获取切入点所在的方法
        Method method = signature.getMethod();
        // 获取操作
        SysAuthorityLog opLog = method.getAnnotation(SysAuthorityLog.class);
        if (opLog != null) {
            String operModul = opLog.value();
            authorityLogEntity.setRemark(operModul);
        }
        // 获取请求的类名
        String className = joinPoint.getTarget().getClass().getName();
        // 获取请求的方法名
        String methodName = method.getName();
        methodName = className + "." + methodName;

        authorityLogEntity.setMethod(methodName); // 请求方法
        // 请求的参数
       // Map<String, String> rtnMap = converMap(request.getParameterMap());
        // 将参数所在的数组转换成json
       //String params = JSON.toJSONString(rtnMap);
      // Map a =  getFieldsName(joinPoint,methodName);
        //拼接入参
        String params= getJosn(joinPoint);
        authorityLogEntity.setParams(params); // 请求参数
        authorityLogEntity.setOldData(JSON.toJSONString(keys)); // 返回结果
        authorityLogEntity.setType(2);
        authorityLogEntity.setIsDelete(0);
        //operlog.setOperUserId(UserShiroUtil.getCurrentUserLoginName()); // 请求用户ID
        //  operlog.setOperUserName(UserShiroUtil.getCurrentUserName()); // 请求用户名称
        // operlog.setOperIp(IPUtil.getRemortIP(request)); // 请求IP

        authorityLogEntity.setIp(ip);
        authorityLogEntity.setOperUrl(requestURI); // 请求URI
        authorityLogEntity.setUpdateTime(new Date()); // 创建时间
        // long endTime = Instant.now().toEpochMilli();
        // authorityLogEntity.setTime(endTime - beginTime);
        //保存进数据库
        authorityLogService.saveE(authorityLogEntity);

    }
    private static HashMap<String, Class> map = new HashMap<String, Class>() {
        {
            put("java.lang.Integer", int.class);
            put("java.lang.Double", double.class);
            put("java.lang.Float", float.class);
            put("java.lang.Long", long.class);
            put("java.lang.Short", short.class);
            put("java.lang.Boolean", boolean.class);
            put("java.lang.Char", char.class);
            put("java.util.Date", Date.class);
            put("java.lang.String", String.class);
        }
    };
    private String getJosn(JoinPoint joinPoint){
       String[] paramname= ((MethodSignature)joinPoint.getSignature()).getParameterNames();
        Object[] args = joinPoint.getArgs();
        StringBuilder sb = new StringBuilder();
        sb.append('{');

        for (int i=0;i<paramname.length;i++){
            if (!ObjectUtils.isEmpty(args[i])){
                if(!"request".equals(paramname[i])){
                    sb.append("\""+paramname[i]+ "\":");
                    sb.append(map.get(args[i].getClass().getName())!=null? "\""+args[i] +"\"":JSONObject.toJSONString(args[i]));
                    sb.append(",");
                }
            }

        }
        sb.append("}");
        return sb.toString();
    }
    /**
     * 转换request 请求参数
     *
     * @param paramMap request获取的参数数组
     */
    public Map<String, String> converMap(Map<String, String[]> paramMap) {
        Map<String, String> rtnMap = new HashMap<String, String>();
        for (String key : paramMap.keySet()) {
            rtnMap.put(key, paramMap.get(key)[0]);
        }
        return rtnMap;
    }


    ///保存薪资变动
    //@Async("Log")
    public void saveSalaryChange(String s, FlowEntity flowEntity, SalaryChangeEntity salaryChangeEntity,String bpmUrl){
        EmployeeInfoEntity employeeInfoEntity = employeeInfoDao.selectOne(new QueryWrapper<EmployeeInfoEntity>()
                .eq("oid", flowEntity.getOid()).eq("is_delete",0));

        JSONArray jsonArray= JSONObject.parseObject(s).getJSONObject("data").getJSONObject("businessObject").getJSONArray("fields");
        int size=jsonArray.size();
        //现月薪标准
        BigDecimal standardMonthlySalary=new BigDecimal(0);
        //现基本工资基数
        BigDecimal baseSalary=new BigDecimal(0);
        //现模块工资基数
        BigDecimal moduleSalaryBase=new BigDecimal(0);
        //申请调整月薪标准
        BigDecimal applyAdjustmentMonthlySalary=new BigDecimal(0);
        //申请调整基本工资基数
        BigDecimal applyBaseSalary=new BigDecimal(0);
        //申请调整模块工资基数
        BigDecimal applyModuleSalaryBase=new BigDecimal(0);
        // 原津贴补助
        BigDecimal originalAllowanceSubsidy=new BigDecimal(0);
        // 拟调整津贴补助
        BigDecimal proposedAdjustmentAllowance=new BigDecimal(0);
        //变动类型
        Integer type=0;
        //调薪日期
        Date effectiveTime=new Date();

        HashMap<String,String> map=new HashMap<>();
        for(int i =0;i<size;i++){
            JSONObject jsonObject= jsonArray.getJSONObject(i);
            String str="";
            if(!StringUtils.isEmpty(jsonObject.getString("value"))){
                str=jsonObject.getString("value").trim();
            }
            str=StringUtils.isEmpty(str)?"0":jsonObject.getString("value").replace("元","");
            map.put(jsonObject.getString("id"),str);
        }
        if (BpmConst.BPM_NEW_EMPLOYEE.equals(flowEntity.getFlowType())){
            //新员工录用   复职录用（1年以上）
            if(0==employeeInfoEntity.getIsReinstate()||3==employeeInfoEntity.getIsReinstate()){
                applyAdjustmentMonthlySalary=getBigDecimal(map.get("probationsalary" ));
                applyBaseSalary=getBigDecimal( map.get("probationbasicsalary"));
                applyModuleSalaryBase= getBigDecimal( map.get("probationmodulesalary"));
            }
          /*  if(3==employeeInfoEntity.getIsReinstate()){
                standardMonthlySalary=getBigDecimal(map.get("oldsalary"));
                baseSalary=getBigDecimal(map.get("oldbasicsalary"));
                moduleSalaryBase=getBigDecimal(map.get("oldmodulesalary"));
            }*/
            // 复职录用（1年以下）
            if(1==employeeInfoEntity.getIsReinstate()){
                standardMonthlySalary=getBigDecimal(map.get("beforesalary"));
                baseSalary=getBigDecimal(map.get("oldbasicsalary"));
                moduleSalaryBase=getBigDecimal(map.get("oldmodulesalary"));
                applyAdjustmentMonthlySalary=getBigDecimal( map.get("resalary"));
                applyBaseSalary= getBigDecimal( map.get("rebasicsalary"));
                applyModuleSalaryBase= getBigDecimal( map.get("remodulesalary"));
            }
            effectiveTime= DateUtils.parseDateYMD(map.get("hiredate"));
            type= SalaryConst.SALARY_TYPE_TRY_OUT;
        }
        //新员工转正
        if (BpmConst.BPM_REGUALR.equals(flowEntity.getFlowType())){
            applyBaseSalary=getBigDecimal( map.get("salary"));
            applyModuleSalaryBase=getBigDecimal(map.get("modulesalary"));
            applyAdjustmentMonthlySalary=applyModuleSalaryBase.add(applyBaseSalary);
            type=SalaryConst.SALARY_TYPE_MANAGEMENT;
            effectiveTime= DateUtils.parseDateYMD(map.get("regularday"));
        }
        //管理晋级转正
        if (BpmConst.MANAGEMENT_BPM_REGUALR.equals(flowEntity.getFlowType())){
            applyBaseSalary=getBigDecimal( map.get("salary"));
            applyModuleSalaryBase=getBigDecimal(map.get("modulesalary"));
            applyAdjustmentMonthlySalary=applyModuleSalaryBase.add(applyBaseSalary);
            type=SalaryConst.SALARY_TYPE_PROFESSION;
            effectiveTime= DateUtils.parseDateYMD(map.get("regulardate"));
        }
        //薪资变动
        if (BpmConst.BPM_FIXED_SALARY.equals(flowEntity.getFlowType())){
            standardMonthlySalary=getBigDecimal(map.get("standardMonthlySalary"));
            baseSalary=getBigDecimal(map.get("baseSalary"));
            moduleSalaryBase=getBigDecimal(map.get("moduleSalaryBase"));
            applyAdjustmentMonthlySalary=getBigDecimal(map.get("applyAdjustmentMonthlySalary"));
            applyBaseSalary= getBigDecimal( map.get("applyBaseSalary"));
            applyModuleSalaryBase= getBigDecimal( map.get("applyModuleSalaryBase"));
            originalAllowanceSubsidy= getBigDecimal( map.get("originalAllowanceSubsidy"));
            proposedAdjustmentAllowance= getBigDecimal(map.get("proposedAdjustmentAllowance"));
            effectiveTime=salaryChangeEntity.getEffectiveTime();
        }
        //调动调薪
        if(BpmConst.BPM_TRANSFER.equals(flowEntity.getFlowType())){
            applyAdjustmentMonthlySalary=getBigDecimal(map.get("afterSalary"));
            applyBaseSalary= getBigDecimal( map.get("afterBase"));
            applyModuleSalaryBase= getBigDecimal( map.get("applyModule"));
            originalAllowanceSubsidy= getBigDecimal( map.get("beforeSubsidy"));
            proposedAdjustmentAllowance= getBigDecimal(map.get("afterSubsidy"));
            String transferType=map.get("transferType");
            if("降级".equals(transferType)){
                type=SalaryConst.SALARY_TYPE_DOWNGRADE;
            }else if("专业晋级".equals(transferType)){
                type=SalaryConst.SALARY_TYPE_ENTRY;
            }else {
                type=SalaryConst.SALARY_TYPE_TRANSFER;
            }
            effectiveTime= DateUtils.parseDateYMD(map.get("hire"));
        }

        if(ObjectUtils.isEmpty(salaryChangeEntity)){
            salaryChangeEntity=new SalaryChangeEntity();
            salaryChangeEntity.setApproveStatus(2);
            salaryChangeEntity.setApplyTime(effectiveTime);
            salaryChangeEntity.setCreateTime(new Date());
            salaryChangeEntity.setIsDelete(0);
            salaryChangeEntity.setStatus(0);
//            salaryChangeEntity.setOrgId(employeeInfoEntity.getOrgId());
            salaryChangeEntity.setUnitId(employeeInfoEntity.getUnitId());
            salaryChangeEntity.setNewJobId(employeeInfoEntity.getJobId());
            salaryChangeEntity.setNewOrgId(employeeInfoEntity.getOrgId());
            salaryChangeEntity.setNewUnitId(employeeInfoEntity.getUnitId());
            salaryChangeEntity.setNewJobLevel(employeeInfoEntity.getJobLevel());
            salaryChangeEntity.setNewJobLevelId(employeeInfoEntity.getJobLevelId());
            salaryChangeEntity.setNewJobLevelType(employeeInfoEntity.getJobLevelType());
            //type=1;
            salaryChangeEntity.setType(type);
        }
        if (BpmConst.BPM_NEW_EMPLOYEE.equals(flowEntity.getFlowType())){
            salaryChangeEntity.setApproveStatus(4);
        }
        salaryChangeEntity.setOid(flowEntity.getOid());

        salaryChangeEntity.setEffectiveTime(effectiveTime);
        //暂时先这样拿
        salaryChangeEntity.setStandardMonthlySalary(standardMonthlySalary);
        salaryChangeEntity.setBaseSalary(baseSalary);
        salaryChangeEntity.setModuleSalaryBase(moduleSalaryBase);

        salaryChangeEntity.setApplyAdjustmentMonthlySalary(applyAdjustmentMonthlySalary);
        salaryChangeEntity.setApplyBaseSalary(applyBaseSalary);
        salaryChangeEntity.setApplyModuleSalaryBase(applyModuleSalaryBase);
        salaryChangeEntity.setOriginalAllowanceSubsidy(originalAllowanceSubsidy);
        salaryChangeEntity.setProposedAdjustmentAllowance(proposedAdjustmentAllowance);

        //异步保存
        saveSalary(salaryChangeEntity,bpmUrl);

        sendSalaryConfirmTodo("您有一位员工薪资审批待确认生效："+employeeInfoEntity.getName(),employeeInfoEntity.getOid(),salaryChangeEntity.getId(),employeeInfoEntity.getOrgId());
    }

    private  BigDecimal getBigDecimal(String str){
        BigDecimal bigDecimal=new BigDecimal(StringUtils.isEmpty(str)?"0":str);
            return bigDecimal;
    }


//    @Async("Log")
//    public void addOperationLog(JoinPoint joinPoint, Object res, long time, HttpServletRequest request) throws Exception {
//        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
//        LogEntity logEntity=new LogEntity();
//        logEntity.setTime(time);
//        logEntity.setCreateDate(new Date());
//        logEntity.setMethod(signature.getDeclaringTypeName() + "." + signature.getName());

//

    private void sendSalaryConfirmTodo(String salaryContent,Long oid,Long relateId,Long orgId){
        qwMsg.sendNoticeMsg("薪资确认",salaryContent, NoticeConst.TODO_TYPE_SALARY_CONFIRM,false,oid,relateId,"薪资确认",null,new Date(),orgId);
    }
    //异步保存用户信息
//    @Async("Log")
//    public void saveEmployeeInfoSchedule(String code, Long oid) {
//        neuEmployeeBaseInfoService.saveAndUpdateEmployeeInfoOne(code,oid+"");
//    }


    //异步初始化用户数据
    @Async("Log")
    public void initializationEmployeeInfo(Long oid) {

        //初始化 主表招聘数据
        LambdaUpdateWrapper<EmployeeInfoEntity> updateWrapper=new LambdaUpdateWrapper<>();
        updateWrapper.set(EmployeeInfoEntity::getStatus,0);
        updateWrapper.set(EmployeeInfoEntity::getCheckUrl,null);
        updateWrapper.set(EmployeeInfoEntity::getIsMemberDone,0);
        updateWrapper.set(EmployeeInfoEntity::getIsHireDone,0);
        updateWrapper.set(EmployeeInfoEntity::getIsRegular,0);
        updateWrapper.set(EmployeeInfoEntity::getRegularIsDone,0);
        updateWrapper.set(EmployeeInfoEntity::getIsOffer,0);
        updateWrapper.set(EmployeeInfoEntity::getIsEntryStatus,0);
        updateWrapper.set(EmployeeInfoEntity::getIsSendContract,0);
        updateWrapper.set(EmployeeInfoEntity::getIsRegularRemind,0);
        updateWrapper.set(EmployeeInfoEntity::getRegularCheckUrl,null);
        updateWrapper.set(EmployeeInfoEntity::getRegularBpmStatus,0);
        updateWrapper.set(EmployeeInfoEntity::getProbationday,null);
        updateWrapper.set(EmployeeInfoEntity::getRegularDay,null);

        updateWrapper.eq(EmployeeInfoEntity::getOid,oid);
        employeeInfoDao.update(null,updateWrapper );
    }

    //异步保存薪资确认信息
    @Async("Log")
    public void saveSalary(SalaryChangeEntity salaryChangeEntity,String bpmUrl) {

        if (salaryChangeEntity.getId()==null){
//            EmployeeInfoEntity employeeInfoEntity= employeeInfoService.getByIdE(salaryChangeEntity.getOid());
//            List<SalaryDto> salaryDtoList= employeeBaseDao.getEmployeeSalaryList(employeeInfoEntity.getCode(),null);
//            if(!CollectionUtils.isEmpty(salaryDtoList)){
//                SalaryDto salaryDto=salaryDtoList.get(0);
//                //暂时先这样拿
//                salaryChangeEntity.setStandardMonthlySalary(getBigDecimal(salaryDto.getTotal()));
//                salaryChangeEntity.setBaseSalary(getBigDecimal(salaryDto.getBsalaryBase()));
//                salaryChangeEntity.setModuleSalaryBase(getBigDecimal(salaryDto.getMkBases()));
//            }
            salaryChangeEntity.setBpmUrl(bpmUrl);
            salaryChangeDao.insert(salaryChangeEntity);
//            neuEmployeeBaseInfoService.sendMq(salaryChangeEntity, EmployeeInfoConst.EMPLOYEE_GET_SALARY,"salaryChangeEntity",false);
        }else {
            salaryChangeService.updateByIdE(salaryChangeEntity);
        }
    }

}
